package components.core
{
    import components.events.ViewPortMaxSizeChangeEvent;
    import components.utils.EventListenerUtil;
    
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.geom.Rectangle;
    
    import mx.events.ResizeEvent;

    [Event(name="maxHeightChange", type="components.events.ViewPortMaxSizeChangeEvent")]
    [Event(name="maxWidthChange", type="components.events.ViewPortMaxSizeChangeEvent")]
    public class Container extends UIComponent implements IViewport
    {
        private var _scrollSprite:Sprite;

        private var _scrolloRect:Rectangle;

        private var _oldMaxWidth:Number;

        private var _oldMaxHeight:Number;

        private var _autoFit:Boolean = false;

        private var _showBackground:Boolean = true;

        public function Container()
        {
            super();

        }

        /***************************************
         *
         * 显示对象声明
         *
         * **************************************/

        /***************************************
         *
         * 验证
         *
         * **************************************/

        protected override function commitProperties():void
        {
            super.commitProperties();

            if (!_initialized)
            {
                _scrollSprite = new Sprite();
                _scrolloRect = new Rectangle(0, 0, 1, 1);
                _scrollSprite.scrollRect = _scrolloRect;

                zn_internal::addChild(_scrollSprite);
            }

            if (backgroundDisplay)
                backgroundDisplay.visible = showBackground;
        }

        protected override function measureSizes():Boolean
        {
            var change:Boolean = super.measureSizes();
            if (change)
            {
                _scrolloRect.width = width;
                _scrolloRect.height = height;
                _scrollSprite.scrollRect = _scrolloRect;

                updateChildSize(_scrollSprite);
            }

            measureChildSize();

            if (autoFit)
                setSize(measureWidth, measureHeight);

            //更新滚屏，以防止滚屏位置大于测量尺寸
            horizontalScrollPosition = horizontalScrollPosition;
            verticalScrollPosition = verticalScrollPosition;

            if (_oldMaxHeight != maxHeight)
            {
                dispatchMaxSizeChangeEvent(ViewPortMaxSizeChangeEvent.MAX_HEIGHT_CHANGE);
                _oldMaxHeight = maxHeight;
            }

            if (_oldMaxWidth != maxWidth)
            {
                dispatchMaxSizeChangeEvent(ViewPortMaxSizeChangeEvent.MAX_WIDTH_CHANGE);
                _oldMaxWidth = maxWidth;
            }

            return change;
        }

        protected override function updateDisplayList():void
        {
            super.updateDisplayList();
        }

        /***************************************
         *
         * 组件定义
         *
         * **************************************/
        [Inspectable(defaultValue="true")]
        public function get showBackground():Boolean
        {
            return _showBackground;
        }

        public function set showBackground(value:Boolean):void
        {
            _showBackground = value;
            invalidate();
        }

        /***************************************
         *
         * 其他代码
         *
         * **************************************/

        public override function addChild(child:DisplayObject):DisplayObject
        {
            addChildAt(child, numChildren);
            return child;
        }

        public override function addChildAt(child:DisplayObject, index:int):DisplayObject
        {
            _scrollSprite.addChildAt(child, index);

            if (child is UIComponent)
            {
				EventListenerUtil.addEventListener(child,ResizeEvent.RESIZE, childSizeChange, false, 0, true);
                UIComponent(child).parent = this;
            }

            invalidate();
            return child;
        }

		public override function getChildByName(name:String):DisplayObject
		{
			return _scrollSprite.getChildByName(name);
		}
		
        public override function removeChild(child:DisplayObject):DisplayObject
        {
            if (_scrollSprite.contains(child))
            {
                _scrollSprite.removeChild(child);

                if (child is UIComponent)
                {
                    UIComponent(child).removeEventListener(ResizeEvent.RESIZE, childSizeChange);
                    UIComponent(child).parent = null;
                }
                invalidate();
            }

            return child;
        }

        public override function removeChildAt(index:int):DisplayObject
        {
            var child:DisplayObject = getChildAt(index);

            removeChild(child);
            return child;
        }

        public override function get numChildren():int
        {
            if (_scrollSprite)
                return _scrollSprite.numChildren;
            return 0;
        }

        override public function getChildAt(index:int):DisplayObject
        {
            if (_scrollSprite)
                return _scrollSprite.getChildAt(index);
            return null;
        }


        public override function getChildIndex(child:DisplayObject):int
        {
            if (_scrollSprite)
                return _scrollSprite.getChildIndex(child);
            return 0;
        }

        public function get contentHeight():Number
        {
            return height;
        }

        public function get contentWidth():Number
        {
            return width;
        }

        public function get horizontalScrollPosition():Number
        {
            return _scrolloRect.x;
        }

        public function set horizontalScrollPosition(value:Number):void
        {
            if (value < 0)
                value = 0;

            var v:Number = measureWidth - contentWidth;
            if (v < 0)
                v = 0;

            value = Math.min(v, value);

            _scrolloRect.x = value;
            _scrollSprite.scrollRect = _scrolloRect;
        }

        public function get maxHeight():Number
        {
            return measureHeight;
        }

        public function get maxHorizontalScrollPosition():Number
        {
            var v:Number = maxWidth - contentWidth;
            if (v < 0)
                v = 0;

            return v;
        }

        public function get maxVerticalScrollPosition():Number
        {
            var v:Number = maxHeight - contentHeight;
            if (v < 0)
                v = 0;

            return v;
        }

        public function get maxWidth():Number
        {
            return measureWidth;
        }

        public function get verticalScrollPosition():Number
        {
            return _scrolloRect.y;
        }

        public function set verticalScrollPosition(value:Number):void
        {
            if (value < 0)
                value = 0;

            var v:Number = measureHeight - contentHeight;
            if (v < 0)
                v = 0;

            value = Math.min(v, value);

            _scrolloRect.y = value;
            _scrollSprite.scrollRect = _scrolloRect;
        }

        protected function dispatchMaxSizeChangeEvent(type:String):void
        {
            var event:ViewPortMaxSizeChangeEvent = new ViewPortMaxSizeChangeEvent(type);
            event.oldMaxHeight = _oldMaxHeight;
            event.oldMaxWidth = _oldMaxWidth;

            dispatchEvent(event);
        }

        protected function childSizeChange(event:ResizeEvent):void
        {
            invalidate();
        }

        public function get autoFit():Boolean
        {
            return _autoFit;
        }

        public function set autoFit(value:Boolean):void
        {
            if (_autoFit == value)
                return;
            _autoFit = value;

            if (value)
                _top = _bottom = _left = _right = _horizontalCenter = _verticalCenter = NaN;

            invalidate();
        }

        public override function destroy():void
        {
            super.destroy();

            _scrolloRect = null;
            _scrollSprite = null;
        }
    }
}